package com.haibara.codesubmiteval.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haibara.codesubmiteval.common.ErrorCode;
import com.haibara.codesubmiteval.constant.AuthConstant;
import com.haibara.codesubmiteval.constant.CommonConstant;
import com.haibara.codesubmiteval.constant.RedisKeyConstant;
import com.haibara.codesubmiteval.context.UserContext;
import com.haibara.codesubmiteval.exception.BusinessException;
import com.haibara.codesubmiteval.exception.ThrowUtils;
import com.haibara.codesubmiteval.mapper.UserMapper;
import com.haibara.codesubmiteval.model.dto.user.UserAddRequest;
import com.haibara.codesubmiteval.model.dto.user.UserChangePasswordRequest;
import com.haibara.codesubmiteval.model.dto.user.UserQueryRequest;
import com.haibara.codesubmiteval.model.dto.user.UserUpdateRequest;
import com.haibara.codesubmiteval.model.entity.User;
import com.haibara.codesubmiteval.model.vo.LoginUserVO;
import com.haibara.codesubmiteval.model.vo.Top10VO;
import com.haibara.codesubmiteval.model.vo.TotalInfo;
import com.haibara.codesubmiteval.model.vo.UserAcceptedQuestionVO;
import com.haibara.codesubmiteval.service.UserService;
import com.haibara.codesubmiteval.utils.RedisRecoveryUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.haibara.codesubmiteval.constant.UserConstant.USER_LOGIN_STATE;

/**
 * 用户服务实现
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    /**
     * 盐值，混淆密码
     */
    private static final String SALT = "haibara";
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedisRecoveryUtil redisRecoveryUtil;
    @Resource
    private UserMapper userMapper;

    /**
     * 用户登录
     *
     * @param id       学号
     * @param password 密码
     * @param request  请求
     * @param response 响应
     * @return 用户脱敏信息
     */
    @Override
    public LoginUserVO userLogin(Long id, String password, HttpServletRequest request, HttpServletResponse response) {
        // 1. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
        User user = this.getBaseMapper().selectById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.PARAMS_ERROR, "用户不存在");
        ThrowUtils.throwIf(!user.getPassword().equals(encryptPassword), ErrorCode.PARAMS_ERROR, "密码错误");
        // 2. 记录用户的登录态
        request.getSession().setAttribute(USER_LOGIN_STATE, user.getId());
        request.getSession().setMaxInactiveInterval(7 * 24 * 60 * 60);
        return LoginUserVO.getLoginUserVOByUser(user);
    }

    /**
     * 获取当前登录用户
     *
     * @param request 请求
     * @return 用户信息
     */
    @Override
    public User getLoginUser(HttpServletRequest request) {
        // 先判断是否已登录
        Object userId = request.getSession().getAttribute(USER_LOGIN_STATE);
        // 用户未登录
        if (userId == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        Long id = (Long) userId;
        String userStr = stringRedisTemplate.opsForValue().get(RedisKeyConstant.getCompleteKey(RedisKeyConstant.userKey, id.toString()));
        if (userStr == null || StrUtil.isBlankIfStr(userStr)) {
            // Redis修复
            userStr = redisRecoveryUtil.recoveryUser(id);
        }
        User currentUser;
        if (userStr == null || StrUtil.isBlankIfStr(userStr)) {
            currentUser = this.baseMapper.selectById(id);
            if (currentUser == null || currentUser.getId() == null) {
                // 数据库中不存在该用户信息
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
            }
        } else {
            currentUser = JSONUtil.toBean(userStr, User.class);
        }
        return currentUser;
    }

    /**
     * 用户注销
     *
     * @param request 请求
     */
    @Override
    public boolean userLogout(HttpServletRequest request) {
        if (request.getSession().getAttribute(USER_LOGIN_STATE) == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
        }
        // 移除登录态
        UserContext.remove();
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        request.getSession().invalidate();
        return true;
    }

    @Override
    public Long addUser(UserAddRequest userAddRequest) {
        Long id = userAddRequest.getId();
        String username = userAddRequest.getUsername();
        String password = userAddRequest.getPassword();
        String clazz = userAddRequest.getClazz();
        String userRole = userAddRequest.getUserRole();
        Integer score = userAddRequest.getScore();
        Set<Long> acceptedQuestionIds = userAddRequest.getAcceptedQuestionIds();
        // 根据新增请求信息创建User对象
        User user = new User();
        user.setId(id);
        user.setUserRole(userRole);
        // 如果用户是管理员，则班级设置为0班
        if (AuthConstant.ADMIN.equals(userRole)) {
            user.setClazz("管理员-0班");
        } else {
            // 如果班级未设定，默认未学号中的班级号
            if (StrUtil.isBlankIfStr(clazz)) {
                user.setClazz(id.toString().substring(2, 8));
            } else {
                user.setClazz(clazz);
            }
        }
        // 如果用户名未设定，则默认为学号
        if (StrUtil.isBlankIfStr(username)) {
            user.setUsername(id.toString());
        } else {
            user.setUsername(username);
        }
        // 如果密码未设定，则默认为学号
        if (StrUtil.isBlankIfStr(password)) {
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + id).getBytes());
            user.setPassword(encryptPassword);
        } else {
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
            user.setPassword(encryptPassword);
        }
        // 设置分数
        user.setScore(Objects.requireNonNullElse(score, 0));
        // 设置完成题目id集合
        if (acceptedQuestionIds == null || acceptedQuestionIds.isEmpty()) {
            user.setAcceptedQuestionIds(JSONUtil.toJsonStr(CommonConstant.getNewSetWith0()));
        } else {
            user.setAcceptedQuestionIds(JSONUtil.toJsonStr(acceptedQuestionIds));
        }
        int insert = this.baseMapper.insert(user);
        ThrowUtils.throwIf(insert == 0, ErrorCode.SYSTEM_ERROR, "数据库新增失败 : " + id);
        // Redis新增完成题目集合
        stringRedisTemplate.opsForSet().add(
                RedisKeyConstant.getCompleteKey(
                        RedisKeyConstant.userAcceptedQuestionIdsSet, user.getId().toString()
                ), "0"
        );
        if (acceptedQuestionIds != null && !acceptedQuestionIds.isEmpty()) {
            for (Long acceptedQuestionId : acceptedQuestionIds) {
                stringRedisTemplate.opsForSet().add(
                        RedisKeyConstant.getCompleteKey(
                                RedisKeyConstant.userAcceptedQuestionIdsSet, user.getId().toString()
                        ), acceptedQuestionId.toString()
                );
            }
        }
        // Redis新增排行榜
        stringRedisTemplate.opsForZSet().add(
                RedisKeyConstant.top10,
                JSONUtil.toJsonStr(Top10VO.builder().userId(user.getId()).build()),
                score
        );
        // 更新Redis AdminIds
        if (user.getUserRole().equals(AuthConstant.ADMIN)) {
            stringRedisTemplate.opsForSet().add(RedisKeyConstant.adminIds, user.getId().toString());
        }
        return id;
    }

    @Override
    @Transactional
    public void updateUser(UserUpdateRequest userUpdateRequest) {
        User user = new User();
        User originUser = this.getById(userUpdateRequest.getId());
        BeanUtils.copyProperties(userUpdateRequest, user);
        // 加密密码
        if (!StrUtil.isBlankIfStr(userUpdateRequest.getPassword())) {
            user.setPassword(DigestUtils.md5DigestAsHex((SALT + userUpdateRequest.getPassword()).getBytes()));
        }
        Integer score = userUpdateRequest.getScore();
        if (score != null && !score.equals(originUser.getScore())) {
            // 修改Redis
            Top10VO top10VO = Top10VO.builder()
                    .userId(user.getId())
                    .build();
            stringRedisTemplate.opsForZSet().add(RedisKeyConstant.top10, JSONUtil.toJsonStr(top10VO), score);
        }
        Set<Long> originSet = new HashSet<>(JSONUtil.toList(originUser.getAcceptedQuestionIds(), Long.class));
        if (userUpdateRequest.getAcceptedQuestionIds() != null && !userUpdateRequest.getAcceptedQuestionIds().isEmpty()) {
            if (
                    originSet.size() != userUpdateRequest.getAcceptedQuestionIds().size() ||
                            !originSet.containsAll(userUpdateRequest.getAcceptedQuestionIds())
            ) {
                // 更新题目通过id集合
                String key = RedisKeyConstant.getCompleteKey(RedisKeyConstant.userAcceptedQuestionIdsSet, user.getId().toString());
                Set<Long> acceptedQuestionIds = userUpdateRequest.getAcceptedQuestionIds();
                stringRedisTemplate.delete(key);
                for (Long acceptedQuestionId : acceptedQuestionIds) {
                    stringRedisTemplate.opsForSet().add(key, acceptedQuestionId.toString());
                }
                // 插入数据库
                user.setAcceptedQuestionIds(JSONUtil.toJsonStr(acceptedQuestionIds));
            }
        }
        int i = this.baseMapper.updateById(user);
        ThrowUtils.throwIf(i != 1, ErrorCode.OPERATION_ERROR);
        // 清除Redis中User缓存
        if (stringRedisTemplate.hasKey(RedisKeyConstant.getCompleteKey(RedisKeyConstant.userKey, user.getId().toString()))) {
            stringRedisTemplate.delete(RedisKeyConstant.getCompleteKey(RedisKeyConstant.userKey, user.getId().toString()));
        }
        // 修改Redis AdminIds
        if (!originUser.getUserRole().equals(user.getUserRole())) {
            if (originUser.getUserRole().equals(AuthConstant.ADMIN)) {
                // 从AdminIds中删除
                stringRedisTemplate.opsForSet().remove(
                        RedisKeyConstant.adminIds,
                        originUser.getId().toString()
                );
            } else {
                // 新增入AdminIds
                stringRedisTemplate.opsForSet().add(
                        RedisKeyConstant.adminIds,
                        originUser.getId().toString()
                );
            }
        }
    }

    @Override
    @Transactional
    public Integer addUserByFile(MultipartFile file) {
        List<String> lines = new ArrayList<>();
        // 从文件中获取按行数据
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                lines.add(line);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 批量新增用户
        List<User> users = new ArrayList<>();
        for (String line : lines) {
            User user = new User();
            String[] userInfo = line.split("\t");
            Long userId = Long.valueOf(userInfo[0]);
            String username = userInfo[1];
            user.setId(userId);
            user.setUsername(username);
            user.setScore(0);
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userInfo[0]).getBytes());
            user.setPassword(encryptPassword);
            // 班级为学号的 3~8 位
            user.setClazz(userInfo[0].substring(2, 8));
            user.setUserRole(AuthConstant.USER);
            user.setAcceptedQuestionIds(JSONUtil.toJsonStr(CommonConstant.getNewSetWith0()));
            users.add(user);
        }
        boolean b = this.saveBatch(users);
        ThrowUtils.throwIf(!b, ErrorCode.SYSTEM_ERROR, "批量新增用户失败");
        // 操作Redis
        for (User user : users) {
            // 题目完成id集合
            stringRedisTemplate.opsForSet().add(
                    RedisKeyConstant.getCompleteKey(RedisKeyConstant.userAcceptedQuestionIdsSet, user.getId().toString()),
                    "0"
            );
            // top10
            Top10VO top10VO = Top10VO.builder()
                    .acceptedQuestionNumber(0L)
                    .userId(user.getId())
                    .build();
            stringRedisTemplate.opsForZSet().add(
                    RedisKeyConstant.top10,
                    JSONUtil.toJsonStr(top10VO),
                    0
            );
        }
        log.info("批量新增用户成功");
        return users.size();
    }

    @Override
    public UserAcceptedQuestionVO getUserCompletionOfTheQuestion(Long userId) {
        ThrowUtils.throwIf(userId == null, ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
        Long acceptedNum = stringRedisTemplate.opsForSet().size(
                RedisKeyConstant.getCompleteKey(
                        RedisKeyConstant.userAcceptedQuestionIdsSet, userId.toString()
                )
        );
        if (acceptedNum == null) {
            // 修复缓存
            acceptedNum = (long) redisRecoveryUtil.recoveryUserQuestionSet(userId).size();
        }
        // 因为在创建用户时，在用户通过题目ids集合中填充了0，所以通过题目数应该 -1
        acceptedNum--;
        String questionNumStr = stringRedisTemplate.opsForValue().get(RedisKeyConstant.questionNumber);
        if (questionNumStr == null) {
            questionNumStr = redisRecoveryUtil.recoveryQuestionNum();
        }
        Long questionNum = Long.parseLong(questionNumStr);
        return UserAcceptedQuestionVO.builder()
                .acceptedQuestionNumber(acceptedNum)
                .remainingQuestionNumber(questionNum - acceptedNum)
                .build();
    }

    @Override
    public List<Top10VO> getTop10Ranking() {
        // 从Redis中获取Top10
        ZSetOperations<String, String> zSetOperations = stringRedisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple<String>> typedTuples = zSetOperations.reverseRangeByScoreWithScores(RedisKeyConstant.top10, 0, 100, 0, 10);
        if (typedTuples == null) {
            typedTuples = redisRecoveryUtil.recoveryTop();
        }
        List<Top10VO> result = new ArrayList<>();
        int rank = 1;
        for (ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
            Top10VO top10VO = JSONUtil.toBean(typedTuple.getValue(), Top10VO.class);
            if (typedTuple.getScore() == null) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "Redis存储完成题目数丢失 : " + top10VO.getUserId());
            }
            double score = typedTuple.getScore();
            top10VO.setScore((int) score);
            // 获取完成题目数
            Long size = stringRedisTemplate.opsForSet().size(RedisKeyConstant.getCompleteKey(RedisKeyConstant.userAcceptedQuestionIdsSet, top10VO.getUserId().toString()));
            if (size == null) {
                // 修复缓存
                size = (long) redisRecoveryUtil.recoveryUserQuestionSet(top10VO.getUserId()).size();
            }
            top10VO.setAcceptedQuestionNumber(size - 1);
            top10VO.setRank(rank++);
            result.add(top10VO);
        }
        return result;
    }

    @Override
    public Top10VO getMyRank(Long userId) {
        ThrowUtils.throwIf(userId == null, ErrorCode.NOT_LOGIN_ERROR);
        Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(RedisKeyConstant.top10, 0, Integer.MAX_VALUE, 0, -1);
        if (typedTuples == null) {
            typedTuples = redisRecoveryUtil.recoveryTop();
        }
        int rank = 1;
        for (ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
            ThrowUtils.throwIf(typedTuple == null, ErrorCode.SYSTEM_ERROR, "Redis缓存失效");
            String jsonStr = typedTuple.getValue();
            ThrowUtils.throwIf(jsonStr == null, ErrorCode.SYSTEM_ERROR, "Redis缓存失效");
            Top10VO top10VO = JSONUtil.toBean(jsonStr, Top10VO.class);
            if (Objects.equals(top10VO.getUserId(), userId)) {
                ThrowUtils.throwIf(typedTuple.getScore() == null, ErrorCode.SYSTEM_ERROR, "Redis缓存失效");
                double score = typedTuple.getScore();
                top10VO.setScore((int) score);
                top10VO.setRank(rank);
                return top10VO;
            }
            rank++;
        }
        return Top10VO.builder()
                .userId(userId)
                .rank(rank)
                .score(0)
                .build();
    }

    @Override
    public void changePassword(UserChangePasswordRequest userChangePasswordRequest) {
        String oldPassword = userChangePasswordRequest.getOldPassword();
        String newPassword = userChangePasswordRequest.getNewPassword();
        String ensurePassword = userChangePasswordRequest.getEnsurePassword();
        Long userId = UserContext.get().getId();
        User user = this.getBaseMapper().selectById(userId);
        // 判断旧密码是否正确
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + oldPassword).getBytes());
        ThrowUtils.throwIf(!encryptPassword.equals(user.getPassword()), ErrorCode.PARAMS_ERROR, "旧密码不正确");
        // 判断新密码和确认密码是否相同
        ThrowUtils.throwIf(!newPassword.equals(ensurePassword), ErrorCode.PARAMS_ERROR, "新密码与确认密码不同");
        // 修改密码
        User updateUser = new User();
        updateUser.setId(userId);
        encryptPassword = DigestUtils.md5DigestAsHex((SALT + newPassword).getBytes());
        updateUser.setPassword(encryptPassword);
        int i = this.getBaseMapper().updateById(updateUser);
        ThrowUtils.throwIf(i != 1, ErrorCode.SYSTEM_ERROR, "数据库异常");
    }

    @Override
    public TotalInfo getTotalInfo() {
        // 总用户数
        String pattern = RedisKeyConstant.getCompleteKey(RedisKeyConstant.userAcceptedQuestionIdsSet, "*");
        Set<String> keys = new HashSet<>();
        try (Cursor<String> cursor = stringRedisTemplate.scan(
                ScanOptions.scanOptions()
                        .match(pattern)
                        .count(200) // 每批扫描数量
                        .build())) {
            while (cursor.hasNext()) {
                keys.add(cursor.next());
            }
        }
        if (keys.isEmpty()) {
            log.error("Redis : AcceptedQuestionNumber数据为空，需要检查!");
        }
        // 从keys中获取用户id
        Set<String> ids = new HashSet<>(keys.stream().map(
                s -> s.substring(s.lastIndexOf(':') + 1)
        ).toList());
        ThrowUtils.throwIf(keys.isEmpty(), ErrorCode.SYSTEM_ERROR, "数据异常，请联系管理员！");
        // 获取管理员id列表
        Set<String> adminIdsStr = stringRedisTemplate.opsForSet().members(RedisKeyConstant.adminIds);
        if (adminIdsStr == null || adminIdsStr.isEmpty()) {
            adminIdsStr = redisRecoveryUtil.recoveryAdminIds();
        }
        if (adminIdsStr.isEmpty()) {
            log.error("Redis : AdminIds数据为空，需要检查!");
        }
        Set<Long> adminIds = adminIdsStr.stream().map(Long::parseLong).collect(Collectors.toSet());
        int userNumber = keys.size() - adminIds.size();
        // 如果没有普通用户，快速返回数据
        if (userNumber == 0) {
            log.warn("系统无普通用户");
            return TotalInfo.builder()
                    .averageAcceptedQuestionNumber(0L)
                    .averageScore(0L)
                    .build();
        }
        // 总题目通过数
        List<Long> sizes = stringRedisTemplate.executePipelined(
                        (RedisCallback<Object>) connection -> {
                            for (String key : ids) {
                                Long userId = Long.parseLong(key); // 确保正确解析用户ID
                                if (!adminIds.contains(userId)) {
                                    connection.setCommands().sCard(
                                            RedisKeyConstant.getCompleteKey(RedisKeyConstant.userAcceptedQuestionIdsSet, key)
                                                    .getBytes(StandardCharsets.UTF_8));
                                }
                            }
                            return null;
                        }
                ).stream()
                .map(obj -> {
                    // 处理Pipeline返回的字节数组
                    if (obj instanceof byte[]) {
                        return Long.parseLong(new String((byte[]) obj));
                    }
                    return (Long) obj;
                })
                .toList();
        long totalQuestionAcceptedNumber = 0L;
        int index = 0;
        for (String key : ids) {
            if (!adminIds.contains(Long.parseLong(key))) {
                Long size = sizes.get(index++);
                totalQuestionAcceptedNumber += (size != null ?
                        size :
                        redisRecoveryUtil.recoveryUserQuestionSet(Long.parseLong(key)).size()
                ) - 1;
            }
        }
        // 总分
        Set<ZSetOperations.TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet()
                .rangeWithScores(RedisKeyConstant.top10, 0, -1); // 0到-1表示获取全部元素
        if (tuples == null || tuples.isEmpty()) {
            tuples = redisRecoveryUtil.recoveryTop();
        }
        long totalScore = 0;
        for (ZSetOperations.TypedTuple<String> tuple : tuples) {
            totalScore += (long) (tuple.getScore() != null ? tuple.getScore() : 0);
        }
        return TotalInfo.builder()
                .averageScore(totalScore / userNumber)
                .averageAcceptedQuestionNumber(totalQuestionAcceptedNumber / userNumber)
                .build();
    }

    @Override
    public List<Long> getMyAcceptedQuestion(Long userId) {
        // 获取用户通过题目id集合
        Set<String> members = stringRedisTemplate.opsForSet().members(
                RedisKeyConstant.getCompleteKey(
                        RedisKeyConstant.userAcceptedQuestionIdsSet,
                        userId.toString()
                )
        );
        if (members == null || members.isEmpty()) {
            members = redisRecoveryUtil.recoveryUserQuestionSet(userId);
        }
        return members.stream().map(Long::parseLong).toList();
    }

    @Override
    public void deleteUser(Long id) {
        boolean b = this.removeById(id);
        // 删除Redis中该用户的完成题目集合
        stringRedisTemplate.delete(RedisKeyConstant.getCompleteKey(RedisKeyConstant.userAcceptedQuestionIdsSet, id.toString()));
        // 删除Redis排行榜对应信息
        // 从Redis中获取Top10
        Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(RedisKeyConstant.top10, 0, 100, 0, 10);
        if (typedTuples == null) {
            typedTuples = redisRecoveryUtil.recoveryTop();
        }
        for (ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
            Top10VO top10VO = JSONUtil.toBean(typedTuple.getValue(), Top10VO.class);
            if (Objects.equals(top10VO.getUserId(), id)) {
                // 删除该数据
                stringRedisTemplate.opsForZSet().remove(RedisKeyConstant.top10, typedTuple.getValue());
            }
        }
        // 删除用户缓存
        stringRedisTemplate.delete(RedisKeyConstant.getCompleteKey(RedisKeyConstant.userKey, id.toString()));
        // 删除Redis AdminIds
        if (Boolean.TRUE.equals(stringRedisTemplate.opsForSet().isMember(
                RedisKeyConstant.adminIds,
                id.toString()
        ))) {
            // 删除
            stringRedisTemplate.opsForSet().remove(
                    RedisKeyConstant.adminIds,
                    id.toString()
            );
        }
    }


    @Override
    public Page<User> pageQueryUser(UserQueryRequest userQueryRequest) {
        Long id = userQueryRequest.getId();
        String username = userQueryRequest.getUsername();
        String clazz = userQueryRequest.getClazz();
        String userRole = userQueryRequest.getUserRole();
        long current = userQueryRequest.getCurrent();
        long pageSize = userQueryRequest.getPageSize();
        String sortField = userQueryRequest.getSortField();
        String sortOrder = userQueryRequest.getSortOrder();
        // 构建查询条件
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        // 过滤
        lqw.eq(id != null, User::getId, id)
                .like(!StrUtil.isBlankIfStr(username), User::getUsername, username)
                .like(!StrUtil.isBlankIfStr(clazz), User::getClazz, clazz)
                .eq(!StrUtil.isBlankIfStr(userRole), User::getUserRole, userRole);
        // 排序
        if (!StrUtil.isBlankIfStr(sortField)) {
            // 根据用户创建时间排序
            lqw.orderBy("createTime".equals(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), User::getCreateTime);
            // 根据用户id排序
            lqw.orderBy("id".equals(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), User::getId);
            lqw.orderBy("score".equals(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), User::getScore);
        }
        // 分页
        return this.page(new Page<>(current, pageSize), lqw);
    }
}
